package terra.slick;

import java.awt.Font;
import java.io.File;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import org.jboss.netty.util.internal.ConcurrentHashMap;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.GL11;
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.UnicodeFont;
import org.newdawn.slick.font.effects.ColorEffect;
import org.newdawn.slick.imageout.ImageOut;
import org.newdawn.slick.state.StateBasedGame;
import org.newdawn.slick.util.FontUtils;

import terra.Config;
import terra.Game;
import terra.Loader;
import terra.definitions.GroundDef;
import terra.definitions.item.ItemDef;
import terra.managers.DefManager;
import terra.managers.LightManager;
import terra.managers.MapManager;
import terra.managers.ResourceManager;
import terra.model.GameObject;
import terra.model.GameObject.ObjectType;
import terra.model.InventoryState;
import terra.model.Light;
import terra.model.MapObject;
import terra.model.Player;
import terra.model.WeatherSystem;
import terra.model.effect.AbstractEffect;
import terra.network.packet.client.ClientResolution;
import terra.network.packet.client.PlayerControl;
import terra.twl.BasicTWLGameState;
import terra.twl.RootPane;
import terra.twl.TWLStateBasedGame;
import terra.twl.window.CharacterPanel;
import terra.twl.window.ChatPanel;
import terra.twl.window.CountChooser;
import terra.twl.window.CraftPanel;
import terra.twl.window.HpBar;
import terra.twl.window.InventoryPanel;
import de.matthiasmann.twl.Button;
import de.matthiasmann.twl.FPSCounter;
import de.matthiasmann.twl.Label;
import de.matthiasmann.twl.ResizableFrame;

public class GameState extends BasicTWLGameState
{
	private float offsetX,offsetY;
	private int tiledOffsetX,tiledOffsetY;	
	private int x,y; 

	private GameContainer gc;
	private static GameState instance;

	public static Color skyColor;
	public static Color waterColor;
	static Image skyImage;
	static Image waterImage;
	
	public static Random rnd = new Random();
	
	public static UnicodeFont font10;
	public static UnicodeFont font12;
	
	public HashMap<Integer,Boolean> keyMap = new HashMap<Integer,Boolean>();
	public HashMap<Integer,Boolean> oldKeyMap = new HashMap<Integer,Boolean>();
	
	public ConcurrentHashMap<Integer,GameObject> objects = new ConcurrentHashMap<Integer,GameObject>();
	public ArrayList<AbstractEffect> effects = new ArrayList<AbstractEffect>();
	
	public Player player;
	public InventoryState inventory = new InventoryState();
	public float lightIntense = 0;
	public byte currentTimeOfDay = 2;
	Color bg = new Color(135, 206, 235);
	Image cursor;
	PlayerControl pc = new PlayerControl();
	MapObject targetMap;
	GameObject targetObj;
	public long lastChunkSended = 0;
	
	@SuppressWarnings("unchecked")
	@Override
	public void init(GameContainer c, StateBasedGame game)	throws SlickException {
		c.setMouseCursor(ResourceManager.getImage("cursor_0"), 0, 0);
		cursor = ResourceManager.getImage("cursor_0");
		rnd.setSeed(2352262656852L);
		font10 = new UnicodeFont(new Font("Tahoma", Font.PLAIN, 10));
		font10.getEffects().add(new ColorEffect(java.awt.Color.white)); 
		font10.addAsciiGlyphs(); 
		font10.addGlyphs(0x400,0x455);
		font10.loadGlyphs();		
		font12 = new UnicodeFont(new Font("Tahoma", Font.PLAIN, 12));
		font12.getEffects().add(new ColorEffect(java.awt.Color.white)); 
		font12.addAsciiGlyphs(); 
		font12.addGlyphs(0x400,0x455);
		font12.loadGlyphs();
		gc = c;
		for(int i = 0; i < 1024; i++) {
			keyMap.put(i, false);
			oldKeyMap.put(i, false);
		}
		skyColor = new Color(135, 206, 235);
		waterColor = new Color(48,95,227);
		skyImage = new Image(Config.tileSize,Config.tileSize);
		skyImage.getGraphics().setColor(new Color(135, 206, 235));
		skyImage.getGraphics().fillRect(0, 0, Config.tileSize, Config.tileSize);
		skyImage.getGraphics().flush();
		skyImage.bind();
		ResourceManager.addImage(skyImage, "block_sky");
		waterImage = new Image(Config.tileSize,Config.tileSize);
		waterImage.getGraphics().setColor(new Color(48,95,227,170));
		waterImage.getGraphics().fillRect(0, 0, Config.tileSize, Config.tileSize);
		waterImage.getGraphics().flush();
		waterImage.bind();
		LightManager.getInstance().boolMap = new byte[getGc().getWidth()/Config.tileSize+8][getGc().getHeight()/Config.tileSize+8];
		LightManager.getInstance().setWidthInTiles(getGc().getWidth()/Config.tileSize+8);
		LightManager.getInstance().setHeightInTiles(getGc().getHeight()/Config.tileSize+8);
		format.applyPattern("#0.0#");
	}
	DecimalFormat format = new DecimalFormat();
	
	@Override
	public void render(GameContainer container, StateBasedGame game, Graphics g) throws SlickException {
		g.translate(-getOffsetX(), -getOffsetY());
		g.setColor(Color.white);
		g.setBackground(Color.black);
		int x1 = getTiledOffsetX()-4;
		int y1 = getTiledOffsetY()-4;
		int x2 = x1 +getGc().getWidth()/Config.tileSize+8;
		int y2 = y1 + getGc().getHeight()/Config.tileSize+8;
		for(int y = y1;y < y2;y++){
		Map<Integer,MapObject> map = MapManager.getInstance().getMap().get(y);
			if (map == null)
				continue;
			for(int x = x1;x < x2;x++){
				MapObject object = map.get(x);
//				MapObject object = MapManager.getInstance().getTile(x, y);
				if (Config.disableLighting)
					drawMapObject(object, x, y, g);
				else if (LightManager.getInstance().boolMap[x-x1][y-y1] != 3
						|| LightManager.getInstance().getLightValue()[x-x1][y-y1][0][0] >= 0.01f)
						drawMapObject(object, x, y, g);
			}
		}

//		for(int x = 0;x < getGc().getWidth()/Config.tileSize+8;x++){
//			for(int y = 0;y < getGc().getHeight()/Config.tileSize+8;y++){			
//				Color c = new Color(Color.red.getRed(),Color.red.getGreen(),Color.red.getBlue(),0.2f);
//				if (LightManager.getInstance().boolMap[x][y] == 3)
//					c = new Color(Color.white.getRed(),Color.white.getGreen(),Color.white.getBlue(),0.2f);
//				else if (LightManager.getInstance().boolMap[x][y] == 1)
//					c = new Color(Color.green.getRed(),Color.green.getGreen(),Color.green.getBlue(),0.2f);
//				g.setColor(c);
//				g.fillRect((getTiledOffsetX()-4+x)*Config.tileSize, (getTiledOffsetY()-4+y)*Config.tileSize, 16, 16);
////				g.setColor(Color.white);
////				g.setFont(font10);
////				if (LightManager.getInstance().getLightValue()[x][y][0][0] != 0)
////					g.drawString(format.format(LightManager.getInstance().getLightValue()[x][y][0][0]), (getTiledOffsetX()-4+x)*Config.tileSize, (getTiledOffsetY()-4+y)*Config.tileSize);
//			}
//		}
		for (GameObject object: objects.values()) {
			if (object.getType() == ObjectType.ARROW) {
				object.render(g);
			} else if (object.getType() == ObjectType.PLAYER) {
				Player p = (Player) object;
				if (p.getCurrentHp() <= 0)
					continue;
				p.render(g);
			} else if  (object.getType() == ObjectType.DOOR) {
				object.render(g);
			} else if (object.getType() == ObjectType.ITEM) {
				Image img = ResourceManager.getImage(DefManager.allItems.get(object.getId()).image);
				LightManager.getInstance().blend((int)(object.getX()/Config.tileSize-x1),(int)(object.getY()/Config.tileSize-y1), img);
				img.draw(object.getX(), object.getY(), Config.tileSize,  Config.tileSize);
			} else if (object.getType() == ObjectType.LIGHT) {
				object.render(g);
			} else if (object.getType() == ObjectType.NPC) {
				Image img = ResourceManager.getImage(DefManager.npcDefs.get(object.getId()).getStringProperty("image"));
				LightManager.getInstance().blend((int)(object.getX()/Config.tileSize-x1),(int)(object.getY()/Config.tileSize-y1), img);
				if (!object.isLeft())
					img.draw(object.getX(), object.getY(),object.getW(), object.getH());
				else {
					Image flipped = img.getFlippedCopy(true, false);
					LightManager.getInstance().blend((int)(object.getX()/Config.tileSize-x1),(int)(object.getY()/Config.tileSize-y1), flipped);
					flipped.draw(object.getX(), object.getY(),object.getW(), object.getH());
				}
			}
		}
		
		for(int i = 0 ; i < effects.size();i++) {
			effects.get(i).draw(g);
		}		
		
		WeatherSystem.draw(g);
		
		if (altPressed()) {
			if (inventory.constructable != -1){
				ItemDef def = DefManager.allItems.get(inventory.constructable);
				if (def.constructGroundId!= -1) {
					Image img = ResourceManager.getImage(DefManager.groundDefs.get(def.constructGroundId).image);
					LightManager.eraseBlend(img);
					img.draw(getOffsetX()+getX(),getOffsetY()+ getY(), Config.tileSize, Config.tileSize);
				}
				if (def.constructObjectId != -1){
					Image img = ResourceManager.getImage(DefManager.npcDefs.get(def.constructObjectId).getStringProperty("image"));
					LightManager.eraseBlend(img);
					img.draw(getOffsetX()+getX(),getOffsetY()+ getY());
				}
			}
		}
		g.resetTransform();
		if (targetMap!= null)
			g.drawString("target hp "+ targetMap.hp , 300, 20);
		
		if (System.currentTimeMillis() < lastChunkSended + 5000)
			FontUtils.drawCenter(font12, "Wait please. Downloading map from server", 0, 100, getGc().getWidth());
	}
	
	int count = 0;
	
	private void drawMapObject(MapObject obj,int x,int y,Graphics g) {
			int xx = getTiledOffsetX()-4;
			int yy = getTiledOffsetY()-4;
			count++;
			if (obj == null){
				LightManager.getInstance().blend(x-xx, y-yy, skyImage);
				skyImage.draw(x*Config.tileSize, y*Config.tileSize);
			} else if (obj.type == MapObject.TYPE_WATER){
				if (obj.id >= 0) {
					GroundDef def = MapManager.getInstance().getDef(obj.id);
					Image image = ResourceManager.getImage(def.image+"_back");
					LightManager.getInstance().blend(x-xx, y-yy, image);
					image.draw(obj.x*Config.tileSize, obj.y*Config.tileSize);
				} else {
					LightManager.getInstance().blend(x-xx, y-yy, skyImage);
					skyImage.draw(x*Config.tileSize, y*Config.tileSize);
				}
				float m = obj.mass;
				if (obj.mass > 1.0f)
					obj.mass = 1.0f;
				LightManager.getInstance().blend(x-xx, y-yy, waterImage);
				waterImage.draw(obj.x*Config.tileSize, obj.y*Config.tileSize+(Config.tileSize-Config.tileSize*m),Config.tileSize,Config.tileSize*m);
			} else if (obj.type == MapObject.TYPE_GROUND) {
				if (obj.neighbors)
					return;
				if (obj.bgId != -1){
					Image back = ResourceManager.getImage(MapManager.getInstance().getDef(obj.bgId).image);
					LightManager.getInstance().blend(x-xx, y-yy, back);
					back.draw(obj.x*Config.tileSize, obj.y*Config.tileSize);
				}
				GroundDef def = MapManager.getInstance().getDef(obj.id);
				Image image = ResourceManager.getImage(def.image);
				LightManager.getInstance().blend(x-xx, y-yy, image);
				image.draw(obj.x*Config.tileSize, obj.y*Config.tileSize);

				if (def.resourceImage != null) {
					Image resource = ResourceManager.getImage(def.resourceImage);
					LightManager.getInstance().blend(x-xx, y-yy, resource);
					resource.draw(obj.x*Config.tileSize, obj.y*Config.tileSize, Config.tileSize, Config.tileSize);
				}
			} else {
				if (obj.id >= 0) {
					GroundDef def = MapManager.getInstance().getDef(obj.id);
					Image image = ResourceManager.getImage(def.image+"_back");
					LightManager.getInstance().blend(x-xx, y-yy, image);
					image.draw(obj.x*Config.tileSize, obj.y*Config.tileSize);
				} else {
					LightManager.getInstance().blend(x-xx, y-yy, skyImage);
					skyImage.draw(obj.x*Config.tileSize, obj.y*Config.tileSize);
				}
			}
	}
	
	public void updateOffset() {
		if (player == null)
			return;
        setOffsetX((int) player.getX() - getGc().getWidth() / 2);
        setOffsetY((int) player.getY() - getGc().getHeight() / 2);
		setTiledOffsetX((int) ((offsetX - offsetX%Config.tileSize)/Config.tileSize));
		setTiledOffsetY((int) ((offsetY - offsetY%Config.tileSize)/Config.tileSize));
		if (LightManager.getInstance().getPlayerLight() != null) {
		    LightManager.getInstance().getPlayerLight().setCenterX(player.getX());
		    LightManager.getInstance().getPlayerLight().setCenterY(player.getY());	
		}
	}

	@Override
	public void update(GameContainer container, StateBasedGame game, int delta)
			throws SlickException {
		if (altPressed()){
			int offsetX = (int) (getOffsetX()%Config.tileSize);
			int offsetY = (int) (Config.tileSize-getOffsetY()%Config.tileSize);
			if (getOffsetX() > 0)
				setX((int) (getX()-getX()%Config.tileSize+(Config.tileSize-offsetX)));
			else
				setX((int) (getX()-getX()%Config.tileSize-offsetX));
			setY((int) (getY()-getY()%Config.tileSize+offsetY));
			System.out.println("offsets: "+ offsetX + " ; " + offsetY);
		}
		
		pingCounter.setText("Ping "+ Loader.handler.ping);
		bg = new Color(skyColor);
		bg.scale(lightIntense);
		updateMouseCursor(gc);

		pc.ALT = altPressed();
		pc.CTRL = ctrlPressed();
		pc.JUMP = isPressed(Input.KEY_SPACE);
		pc.UP = isPressed(Input.KEY_W);
		pc.DOWN = isPressed(Input.KEY_S);
		pc.LEFT = isPressed(Input.KEY_A);
		pc.RIGHT = isPressed(Input.KEY_D);
		pc.LMB = lmb;
		pc.RMB = rmb;
		pc.mouseX = (int) (getX()+getOffsetX());
		pc.mouseY = (int) (getY()+getOffsetY());
		Loader.handler.send(pc);
		
		for(GameObject obj : objects.values())
			obj.update(delta);
		
		int x1 = GameState.getInstance().getTiledOffsetX()+x/Config.tileSize;
		int y1 = GameState.getInstance().getTiledOffsetY()+y/Config.tileSize;
		MapObject object = MapManager.getInstance().getTile(x1, y1);
		targetMap = object;
		
		for (int i = 0 ; i <  effects.size();i++) {
			AbstractEffect effect =  effects.get(i);
			effect.update(delta);
			if (effect.remove)
				effects.remove(effect);
		}
		updateOffset();
		
    	if (!Config.disableLighting){
			x1 = getTiledOffsetX()-4;
			y1 = getTiledOffsetY()-4;
			int x2 = x1 +getGc().getWidth()/Config.tileSize+8;
			int y2 = y1 + getGc().getHeight()/Config.tileSize+8;
			
//			for(int x = x1;x < x2;x++){
//				for(int y = y1;y < y2;y++){
//					object = MapManager.getInstance().getTile(x, y);
			for(int y = y1;y < y2;y++){
				Map<Integer,MapObject> map = MapManager.getInstance().getMap().get(y);
				if (map == null)
					continue;
					for(int x = x1;x < x2;x++){
						object = map.get(x);
						if (object == null){
							LightManager.getInstance().boolMap[x-x1][y-y1] = 2;
							continue;
						}
						if (object.neighbors)
							LightManager.getInstance().boolMap[x-x1][y-y1] = 3;
						else if (object.type != MapObject.TYPE_GROUND && object.id < 0)
							LightManager.getInstance().boolMap[x-x1][y-y1] = 2;
						else if (object.type == MapObject.TYPE_GROUND){
							if (object.id >= 21 && object.id <=24)
								LightManager.getInstance().boolMap[x-x1][y-y1] = 2;
							else
								LightManager.getInstance().boolMap[x-x1][y-y1] = 0;	
						} else
							LightManager.getInstance().boolMap[x-x1][y-y1] = 1;
				}
			}
    	}
		WeatherSystem.update(delta);
		
        if(chatPanel.isAtEnd) {
            GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
            chatPanel.scrollPane.validateLayout();
            chatPanel.scrollPane.getVerticalScrollbar().scroll(chatPanel.scrollPane.getVerticalScrollbar().getMaxValue());
            GL11.glPopAttrib();
            chatPanel.isAtEnd = false;
        }
        LightManager.getInstance().updateLightMap();	
	}

	void updateMouseCursor(GameContainer gc) {
		/*if (getTargetObject() instanceof Attackable)
		{
			cursor = ResourceManager.getImage("cursor_3");
			return;
		}
		if (getTargetObject() instanceof Interactable)
		{
			cursor = ResourceManager.getImage("cursor_2");	
			return;
		}*/

//		if (GUI.guiHasFocus()){
//			cursor = ResourceManager.getImage("cursor_2");
//			return;				
//		}
		if (altPressed()){
			cursor = ResourceManager.getImage("cursor_1");
			return;	
		}
		cursor = ResourceManager.getImage("cursor_0");
		return;
     }
	
	public void keyPressed(int key, char c) {
		boolean old = keyMap.put(key, true);
		oldKeyMap.put(key, old);
		if (key == Input.KEY_1)
			inventory.useShorCut(0);
		else if (key == Input.KEY_2)
			inventory.useShorCut(1);
		else if (key == Input.KEY_3)
			inventory.useShorCut(2);
		else if (key == Input.KEY_4)
			inventory.useShorCut(3);
		else if (key == Input.KEY_5)
			inventory.useShorCut(4);
		else if (key == Input.KEY_6)
			inventory.useShorCut(5);
		else if (key == Input.KEY_7)
			inventory.useShorCut(6);
		else if (key == Input.KEY_8)
			inventory.useShorCut(7);
		else if (key == Input.KEY_9)
			inventory.useShorCut(8);
		else if (key == Input.KEY_0)
			inventory.useShorCut(9);
		else if (key == Input.KEY_E)
			inventoryWindow.setVisible(!inventoryWindow.isVisible());
		else if (key == Input.KEY_C)
			characterWindow.setVisible(!characterWindow.isVisible());
		else if (key == Input.KEY_T)
			craftWindow.setVisible(!craftWindow.isVisible());
	}

	public void keyReleased(int key, char c) {
		boolean old = keyMap.put(key, false);
		oldKeyMap.put(key, old);
		if (key == Input.KEY_F12)
			changeResolution(Display.getDesktopDisplayMode().getWidth(),Display.getDesktopDisplayMode().getHeight(),false);
		else if (key == Input.KEY_F10)
			screenShot();
	}

	private void screenShot() {
		Image target;
		try	{
			target = new Image(getGc().getWidth(), getGc().getHeight());
			getGc().getGraphics().copyArea(target, 0, 0);
			String name = "screen.png";
			int i = 0;
			File f = new File(name);
			while (f.exists()) {
				name = "screen" + i + ".png";
				f = new File(name);
				i++;
			}
			ImageOut.write(target.getFlippedCopy(false, false), name, false);
			target.destroy();
		} catch (SlickException e) {
			e.printStackTrace();
		}
	}	

	boolean lmb = false, rmb = false;
	public void mousePressed(int button, int x, int y) {
		setX(x);
		setY(y);
		if (button == Input.MOUSE_LEFT_BUTTON)
				lmb = true;
		else if (button == Input.MOUSE_RIGHT_BUTTON)
				rmb = true;
	}
	
	public void mouseReleased(int button, int x, int y) {
		setX(x);
		setY(y);
		if (button == Input.MOUSE_LEFT_BUTTON)
			lmb = false;
		else if (button == Input.MOUSE_RIGHT_BUTTON)
			rmb = false; 
	}

	public void mouseWheelMoved(int newValue){

	}
	
	public void mouseDragged(int oldx,int oldy,int newx,int newy) {
		setX(newx);
		setY(newy);
	}
	
	public void mouseMoved(int oldx,int oldy,int newx,int newy) {
		setX(newx);
		setY(newy);
	}

	@Override
	public int getID() {
		return 1;
	}

	public static GameState getInstance() {
		if (instance == null)
			return instance = new GameState();
		return instance;
	}

	public void setOffsetX(float offsetX) {
		this.offsetX = offsetX;
	}

	public float getOffsetX() {
		return offsetX;
	}

	public void setOffsetY(float offsetY) {
		this.offsetY = offsetY;
	}

	public float getOffsetY() {
		return offsetY;
	}

	public void setTiledOffsetX(int tiledOffsetX) {
		this.tiledOffsetX = tiledOffsetX;
	}

	private void setTiledOffsetY(int f) {
		this.tiledOffsetY = f;
	}
	public int getTiledOffsetX() {
		return tiledOffsetX;
	}

	public int getTiledOffsetY() {
		return tiledOffsetY;
	}

	public void setGc(GameContainer gc) {
		this.gc = gc;
	}

	public GameContainer getGc() {
		return gc;
	}
/*
	public AbstractMapObject getTargetMap() {
		return targetMap;
	}

	public void setTargetMap(AbstractMapObject targetMap) {
		this.targetMap = targetMap;
	}

	public GameObject getTargetObject() {
		return targetObject;
	}

	public void setTargetObject(GameObject targetObject) {
		this.targetObject = targetObject;
	}
	*/
	


	public boolean altPressed() {
		return keyMap.get(Input.KEY_LALT);
	}

	public boolean ctrlPressed(){
		return keyMap.get(Input.KEY_LCONTROL);
	}
	
	public boolean isPressed(int key){
		return keyMap.get(key);
	}
	
	public boolean isOldPressed(int key){
		return oldKeyMap.get(key);
	}

	public int getX() {
		return x;
	}

	public void setX(int x) {
		if (x >= 0 && x <= Game.instance.getContainer().getWidth())
			this.x = x;
	}

	public int getY() {
		return y;
	}

	public void setY(int y) {
		if (y >= 0 && y <= Game.instance.getContainer().getHeight())
		this.y = y;
	}
	
	private void changeResolution(int w,int h,boolean fullscreen){
		try {
			if (Game.app instanceof AppGameContainer)
				((AppGameContainer) Game.app).setDisplayMode(w, h, fullscreen);
		} catch (SlickException e) {
			e.printStackTrace();
		}
		finally{
			Loader.handler.send(new ClientResolution(Game.app.getWidth(),Game.app.getHeight(),Game.app.isFullscreen()));
		}
	}

	//public ItemCountWnd itemCountWnd;
	
//	private void initGUI(GameContainer container){
//	     HpBar hpBar = new HpBar(container, null);
//	     hpBar.setArea(new Rectangle(0,0,128,64));
//	     hpBar.setDraggable(true);
//	     hpBar.setAllowVerticalResize(false);
//	     hpBar.setMinWidth(128);
//	     hpBar.setMaxWidth(400);	 
//	     hpBar.setMinHeight(64);
//	     hpBar.setMaxHeight(64);
//	     hpBar.setLocation(0, 0);
//	     hpBar.setResizeShape(new Rectangle(0,0,8,8));
//	     hpBar.resize(0, 0);
//	     QuickBar quickBar = new QuickBar(container, null);
//	     quickBar.setArea(new Rectangle(0,0,GUI.iconSize*11+12+16,38));
//	     quickBar.setHorisontal(false);
//	     quickBar.setLocation(container.getWidth() - quickBar.getWidth()-5, (getGc().getHeight()-quickBar.getHeight())/2);
//	     
//	     inv = new InventoryWnd(container, null);
//		 int width = GUI.inventoryItemsWidth*GUI.iconSize+(GUI.gap+1)*GUI.inventoryItemsWidth;
//		 int height =InventoryWnd.getHeightForCount(inventory.maxCount/GUI.inventoryItemsWidth);
//		 inv.setArea(new Rectangle(0,0,width,height));
//		 inv.setLocation(50, 50);
//		 inv.setVisible(false);
//		 inv.init();
//		 try {
//			itemCountWnd = new ItemCountWnd(container, null);
//		} catch (SlickException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//		 itemCountWnd.setVisible(false);
//		 CraftWnd craftWindow = new CraftWnd(container, null);
//		 craftWindow.setVisible(false);
//		 craftWindow.setArea(new Rectangle(0,0,GUI.craftWidth,GUI.craftHeight));
//		 craftWindow.setLocation(250, 50);
//		 craftWindow.init();
//	     GUI.addWnd(hpBar);
//	     GUI.addWnd(quickBar);
//	     GUI.addWnd(inv);
//	     GUI.addWnd(itemCountWnd);
//	     GUI.addWnd(craftWindow);
//	}
	
	FPSCounter fpsCounter;
	Label fps,pingCounter;
	
	@Override
    protected void layoutRootPane() {
		for(int i = 0; i < getRootPane().getNumChildren();i++)
			getRootPane().getChild(i).adjustSize();
    }
	
	public ResizableFrame inventoryWindow,characterWindow,craftWindow;
	public CharacterPanel characterPanel;
	public CountChooser countchooser;
	public InventoryPanel inventoryPanel;
	public HpBar hpBar;
	public CraftPanel craftPanel;
	public ChatPanel chatPanel;
	
    @Override
    protected RootPane createRootPane() {
    	RootPane rootPane = super.createRootPane();
    	
    	inventoryPanel = new InventoryPanel(4,5);
    	characterPanel = new CharacterPanel();
    	hpBar = new HpBar();
    	hpBar.setTheme("hpbar");
    	ResizableFrame hpbarWindow = new ResizableFrame();
    	hpbarWindow.setTitle("HPbar");
    	hpbarWindow.setTheme("hpbarwindow");
    	hpbarWindow.setDraggable(true);
    	hpbarWindow.setResizableAxis(ResizableFrame.ResizableAxis.HORIZONTAL);
    	hpbarWindow.add(hpBar);
    	hpbarWindow.setVisible(true);
    	hpbarWindow.setPosition(0,0);
    	hpbarWindow.adjustSize();
    	
    	craftPanel  = new CraftPanel(3,3);
    	craftWindow = new ResizableFrame();
    	craftWindow.setTitle("Craft");
    	craftWindow.setTheme("craftframe");
    	craftWindow.setDraggable(true);
    	craftWindow.setResizableAxis(ResizableFrame.ResizableAxis.NONE);
    	craftWindow.add(craftPanel);
    	craftWindow.setVisible(false);
    	craftWindow.setPosition(300,5);
    	craftWindow.adjustSize();
    	craftWindow.addCloseCallback(new Runnable(){
			@Override
			public void run() {
				craftWindow.setVisible(false);
			}});
    	
    	inventoryWindow = new ResizableFrame();
    	inventoryWindow.setTitle("Inventory");
    	inventoryWindow.setDraggable(true);
    	inventoryWindow.setResizableAxis(ResizableFrame.ResizableAxis.NONE);
    	inventoryWindow.add(inventoryPanel);
    	inventoryWindow.setVisible(false);
    	inventoryWindow.addCloseCallback(new Runnable(){
			@Override
			public void run() {
				inventoryWindow.setVisible(false);
			}});
    	
    	characterWindow = new ResizableFrame();
    	characterWindow.setTitle("Character");
    	characterWindow.setDraggable(true);
    	characterWindow.setResizableAxis(ResizableFrame.ResizableAxis.NONE);
    	characterWindow.add(characterPanel);
    	characterWindow.setVisible(false);
    	characterWindow.addCloseCallback(new Runnable(){
			@Override
			public void run() {
				characterWindow.setVisible(false);
			}});    	
    	
    	countchooser = new CountChooser();
    	countchooser.setTitle("Choose count");
    	countchooser.setDraggable(true);
    	countchooser.setResizableAxis(ResizableFrame.ResizableAxis.NONE);
    	countchooser.setVisible(false);
    	countchooser.addCloseCallback(new Runnable(){
			@Override
			public void run() {
				countchooser.setVisible(false);
			}}); 
    	
    	fpsCounter = new FPSCounter(3,1);
    	fps = new Label("FPS");
    	pingCounter = new Label("Ping");
    	chatPanel = new ChatPanel();
    	chatPanel.setPosition(0,getGc().getHeight()-chatPanel.getHeight());
    	chatPanel.addCloseCallback(new Runnable(){
			@Override
			public void run() {
				chatPanel.setVisible(false);
			}});
    	//chatPanel.setSize(250, 200);
    	fps.setTheme("fpscounter");
    	fps.setLabelFor(fpsCounter);
    	pingCounter.setTheme("pingcounter");
    	fpsCounter.setPosition(getGc().getWidth()-fpsCounter.getWidth(), 10);
    	fps.setPosition(getGc().getWidth()-fpsCounter.getWidth()-fps.getWidth()-10, 10);
    	pingCounter.setPosition(getGc().getWidth()-pingCounter.getWidth(), 10);
    	inventoryWindow.setPosition(300,300);
    	characterWindow.setPosition(300,300);
    	countchooser.setPosition(300, 300);
    	Button inventoryButton = new Button();
    	inventoryButton.setTheme("inventorybutton");
    	inventoryButton.setFocusKeyEnabled(false);
    	inventoryButton.addCallback(new Runnable(){
			@Override
			public void run() {
				inventoryWindow.setVisible(!inventoryWindow.isVisible());
				if (inventoryWindow.isVisible()){
					inventoryWindow.requestKeyboardFocus();
					inventoryWindow.focusFirstChild();
				}
//				inventoryButton.giveupKeyboardFocus();
			}});
    	inventoryButton.setPosition(getGc().getWidth()-inventoryButton.getWidth()-5, 100);
    	Button characterButton = new Button();
    	characterButton.setTheme("characterbutton");
    	characterButton.setFocusKeyEnabled(false);
    	characterButton.addCallback(new Runnable(){
			@Override
			public void run() {
				characterWindow.setVisible(!characterWindow.isVisible());
				if (characterWindow.isVisible()){
					characterWindow.requestKeyboardFocus();
					characterWindow.focusFirstChild();
				}
//				characterButton.giveupKeyboardFocus();
			}});
    	characterButton.setPosition(getGc().getWidth()-inventoryButton.getWidth()-5, 140);
    	Button craftButton = new Button();
    	craftButton.setTheme("craftbutton");
    	craftButton.setFocusKeyEnabled(false);
    	craftButton.addCallback(new Runnable(){
			@Override
			public void run() {
				craftWindow.setVisible(!craftWindow.isVisible());
				if (craftWindow.isVisible()){
					craftWindow.focusFirstChild();
					craftWindow.requestKeyboardFocus();
				}
			}});
    	craftButton.setPosition(getGc().getWidth()-inventoryButton.getWidth()-5, 180);
    	
    	
    	Button chatButton = new Button();
    	chatButton.setTheme("chatbutton");
    	chatButton.setFocusKeyEnabled(false);
    	chatButton.addCallback(new Runnable(){
			@Override
			public void run() {
				chatPanel.setVisible(!chatPanel.isVisible());
				if (chatPanel.isVisible()){
					chatPanel.focusFirstChild();
					chatPanel.requestKeyboardFocus();
				}
			}});
    	chatButton.setPosition(getGc().getWidth()-inventoryButton.getWidth()-5, 220);
    	
    	
    	rootPane.add(chatButton);    	
    	rootPane.add(inventoryButton);
    	rootPane.add(characterButton);
    	rootPane.add(craftButton);
    	rootPane.add(hpbarWindow);
    	rootPane.add(craftWindow);
    	rootPane.add(pingCounter);
    	rootPane.add(inventoryWindow);
    	rootPane.add(characterWindow);
    	rootPane.add(countchooser);
    	rootPane.add(chatPanel);
    	return rootPane;
    }
    
	@Override
	public void leave(GameContainer container, StateBasedGame game) throws SlickException	{
		super.leave(container, game);
		getRootPane().destroy();
		MapManager.getInstance().clear();
		effects.clear();
		objects.clear();
		player = null;
		Loader.handler = null;
		inventory.clear();
	}
	
	@Override
	public void enter(GameContainer container, TWLStateBasedGame game) throws SlickException {
		super.enter(container, game);
		getRootPane().reapplyTheme();
		inventoryPanel.update();
		hpBar.update();
		characterPanel.updateHtml();
		Loader.handler.send(new ClientResolution(getGc().getWidth(),getGc().getHeight(),getGc().isFullscreen()));
	    LightManager.getInstance().setLightValue(new float[LightManager.getInstance().getWidthInTiles()][LightManager.getInstance().getHeightInTiles()][4][3]); 
	    LightManager.getInstance().setPlayerLight(new Light(Color.white, 0, 0, 9));
	    LightManager.getInstance().getLights().add(LightManager.getInstance().getPlayerLight());
	}
}
